0100 .OPT NO LIST 0110 ******************************** 0120 * E d i t M a g i c * 0130 * Version 2.0 * 0140 * By Bill Bodenstein * 0150 * For XL/XE systems only * 0160 * 1/23/87 * 0170 ******************************** 0180 ; 0190 ;This program will provide 0200 ;many simple utilities to 0210 ;make editing BASIC and MAC/65 0220 ;listings easier and faster. 0230 ; 0240 ; 0250 *** EQUATES *** 0260 ; 0270 INITCODE = $0500 0280 MAINCODE = $CA60 0290 DISPLIST = $C590 0300 MACLIST = $C600 0310 MISC = $C290 0320 XITVBCODE = $C28A 0330 ; 0340 INITADR = $02E2 0350 RUNADR = $02E0 0360 ; 0370 LMARGIN = $52 0380 RMARGIN = $53 0390 COLCRS = $55 0400 LOGCOL = $63 0410 OLDADR = $5E 0420 OLDCHR = $5D 0430 SAVMSC = $58 0440 DINDEX = $57 0450 ; 0460 BRKKEY = $11 0470 CH = $02FC 0480 KBCODE = $D209 0490 HELPFG = $02DC 0500 KRPDEL = $02D9 0510 KEYREP = $02DA 0520 CONSOL = $D01F 0530 ESCFLG = $02A2 0540 DSPFLG = $02FE 0550 SSFLAG = $02FF 0560 ; 0570 CIX = $F2 0580 INBUFF = $F3 0590 TEXTBUFF = $0580 0600 ICSTAZ = $23 0610 ICBALZ = $24 0620 ICIDNO = $2E 0630 ICPTL = $0346 0640 ICCOM = $0342 0650 ICBAL = $0344 0660 ICBLL = $0348 0670 PAUSEFLG = $034F 0680 CIO = $E456 0690 ; 0700 SDMCTL = $022F 0710 DMACTL = $D400 0720 SDLSTL = $0230 0730 NMIEN = $D40E 0740 PORTB = $D301 0750 COLOR1 = $02C5 0760 COLOR4 = $02C8 0770 COLPF1 = $D017 0780 ; 0790 TRAMSZ = $06 0800 DOSVEC = $0A 0810 COLDST = $0244 0820 ; 0830 EHANDTAB = $E400 0840 KHANDTAB = $E420 0850 ; 0860 PUTREC = 9 0870 SPACE = 32 0880 ESC = 27 0890 CLEAR = 125 0900 DELETE = 126 0910 RETURN = 155 0920 BREAK = 128 0930 NOKEY = 255 0940 ; 0950 ; 0960 *= INITCODE 0970 ; 0980 *** INITIALIZATION *** 0990 ; -------------- 1000 ; Copy o.s. from ROM to RAM and 1010 ;disable ROM to allow rest of 1020 ;Edit Magic code to load there. 1030 ; 1040 INIT 1050 ; 1060 LDA $FFF7 ;Is o.s. from 1070 CMP #2 ;XL/XE machine? 1080 BEQ DISABLED? ;Br if yep 1090 GOEXIT 1100 JMP EXIT ;Else do nothing 1110 ; 1120 DISABLED? 1130 LDA PORTB ;Is os ROM/RAM? 1140 TAX ;Save ROM status 1150 AND #255-1 ;Make disabled 1160 CMP PORTB ;Is it already? 1170 BEQ GOEXIT ;Br if yup 1180 STA $D4 ;Save new status 1190 ; 1200 LDA # <$C000 ;Start copying 1210 STA $D6 ;o.s. from 1220 LDA # >$C000 ;$c000 to $ffff 1230 STA $D7 1240 ; 1250 LDA SDMCTL ;Save DMA status 1260 PHA 1270 LDA #0 ;Disable NMI 1280 STA NMIEN ;so no VBI while 1290 STA SDMCTL ;moving o.s. 1300 STA DMACTL ;Turn screen off 1310 SEI ;No IRQ 1320 ; 1330 LDY #0 1340 COPYO.S. 1350 STX PORTB ;Enable ROM 1360 LDA ($D6),Y ;Get a byte 1370 DEC PORTB ;Enable RAM 1380 STA ($D6),Y ;Put o.s. there 1390 INY 1400 BNE COPYO.S. ;And move more 1410 ; 1420 INC $D7 ;Next page 1430 BEQ NMION ;Done if $0000 1440 LDA $D7 ;Skip over 1450 CMP #$D0 ;hardware chips 1460 BNE COPYO.S. 1470 LDA #$D8 ;Set next page 1480 STA $D7 ;to $D800 1490 JMP COPYO.S. ;and loop back 1500 ; 1510 NMION 1520 CLI ;Re-enable IRQ 1530 LDA #64 ;and non-mskable 1540 STA NMIEN ;interrupts 1550 PLA ;And turn scr 1560 STA SDMCTL ;back on 1570 ; 1580 LDA $D4 ;Make ROM 1590 STA PORTB ;disabled 1600 ; 1610 ;Let user know what's going on 1620 ;with a short message. 1630 ; 1640 LDX #$00 ;Use scr editor 1650 LDA # INITMSG ;message 1680 STA ICBAL+1,X 1690 STA ICBLL+1,X ;Whatever len 1700 LDA #PUTREC ;Print record 1710 STA ICCOM,X 1720 JSR CIO ;CIO prints it 1730 ; 1740 ;Save editor handler's vectors 1750 ;for GET and PUT operations so 1760 ;Edit Magic can call them later. 1770 ; 1780 LDA EGET ;Get vector 1790 STA SAVEGETV 1800 LDA EGET+1 1810 STA SAVEGETV+1 1820 LDA EPUT ;Put vector 1830 STA SAVEPUTV 1840 LDA EPUT+1 1850 STA SAVEPUTV+1 1860 ; 1870 EXIT RTS ;Let DOS load 1880 ; 1890 INITMSG .BYTE "Installing Edit Magic ...",155 1900 ; 1910 *= INITADR 1920 .WORD INIT 1930 ; 1940 ; 1950 *= MAINCODE 1960 ; 1970 *** MAIN CODE *** 1980 ; --------- 1990 ; Edit Magic will be stored 2000 ;over unused o.s. code. 2010 ;(Intrn'l charset,warmstart, 2020 ; and self-test screen data.) 2030 ;There are four entry points: 2040 ;1) From GET operations 2050 ;2) Prior to every keypress 2060 ;3) From PUT operations 2070 ;4) At the end of every VBI 2080 ; 2090 ;GET editor entry: 2100 ;----------------- 2110 ; Handle features before and 2120 ;after getting a line of text 2130 ;from the screen editor. 2140 ; 2150 GETENTRY 2160 ; 2170 LDA #'>-32 ;">" in listbox 2180 STA LISTBOX ;says active 2190 ; 2200 LDX # <[MSG1-MSGS] 2210 JSR PUTMSG ;Display title 2220 ; 2230 LDA SAVECNT ;Get # times 2240 CLC ;file SAVEd 2250 ADC #16 ;Conv to intrnal 2260 BIT SAVEDFLG ;If recently 2270 BEQ PUTCNT ; saved, 2280 ORA #128 ; inverse # 2290 PUTCNT 2300 STA BAKUPCNT ;Put # on scr 2310 ; 2320 LDA EMFLG ;Is Edit Magic 2330 BEQ GOGET ;on? 2340 ; 2350 ; 2360 LDA #0 ;Clear lnno cntr 2370 STA STCKCNT ;for later use 2380 ; 2390 LDA #32 ;Shorter key 2400 STA KRPDEL ;repeat delay 2410 LDA #4 ;and delay 2420 STA KEYREP ;between repeats 2430 ; 2440 LDA XITVBCODE ;Has our jmp 2450 CMP #76 ;been set yet? 2460 BEQ GOGET ;Br if yes 2470 LDA #0 ;Prevent VBI 2480 STA NMIEN 2490 LDA #76 ;JMP op-code 2500 STA XITVBCODE ;Put jmp to 2510 LDA # XITVBI ; in place of 2540 STA XITVBCODE+2 ;system's 2550 LDA #64 ;Allow VBI again 2560 STA NMIEN 2570 ; 2580 ; 2590 GOGET 2600 LDX ICIDNO ;Get iocb index 2610 JSR EGETCHAR ;Let os do work 2620 STY ICSTAZ ;Save status 2630 CPY #BREAK ;Exit if 2640 BCS GOCIO ;pressed 2650 CMP #RETURN ;Or not 2660 BEQ PUTEOL 2670 GOCIO RTS ;Let CIO finish 2680 ; 2690 PUTEOL 2700 LDX #0 ;Put EOL at 2710 STA (ICBALZ,X) ;end of line 2720 ; 2730 LDA EMFLG ;Skip features 2740 BEQ RETCIO2 ;if E.M. off 2750 ; 2760 ; 2770 ;A line of text is in the text 2780 ;buffer. Save line and see if 2790 ;it has a LOAD or SAVE command, 2800 ;or a line number. 2810 ; 2820 LDA TEXTBUFF ;If blank line 2830 CMP #RETURN 2840 BEQ RETCIO2 ; do nothing 2850 ; 2860 ; 2870 LDX #255 ;Save inputted 2880 SAVCHR ; line of text 2890 INX 2900 BMI RETCIO2 ;Emergency exit 2910 LDA TEXTBUFF,X ;Move line 2920 STA SAVTBUFF,X ;to storage 2930 CMP #RETURN ; until eol 2940 BNE SAVCHR 2950 ; 2960 LDA #0 ;For macro: a 2970 STA SAVTBUFF,X ;zero ends 2980 ; 2990 LDX #255 3000 SKIPLEADING 3010 INX 3020 BMI RETCIO2 3030 LDA TEXTBUFF,X ;Skip over 3040 CMP #RETURN ;until eol 3050 BEQ RETCIO2 3060 CMP #SPACE ;leading blanks 3070 BEQ SKIPLEADING 3080 CMP #'0 ;and leading 0's 3090 BEQ SKIPLEADING 3100 ; 3110 STX CIX ;Save index 3120 ; 3130 LNNO? 3140 LDA TEXTBUFF,X 3150 CMP #'1 ;Is line begun 3160 BCC LOAD? ;by linenum? 3170 CMP #'9+1 3180 BCS LOAD? 3190 ; 3200 LDA #0 ;Remind user 3210 STA SAVEDFLG ;program has 3220 ; been modified 3230 LDA LNNOCNT ;Save linenum in 3240 STA $E0 ;stack if room 3250 CMP #24 ;Only sav 24 #'s 3260 BCS RETCIO2 3270 ; 3280 LDA # LNNOSTACK ;stack? 3300 LOOKSTACK 3310 DEC $E0 ;Look thru stack 3320 BMI PUTINSTACK ;Br when done 3330 JSR CMPTEXT ;Compare nums 3340 BMI RETCIO2 ;Exit if # there 3350 ; 3360 CLC ;Each lnno in 3370 ADC #5 ;stack is 5 chrs 3380 BCC LOOKSTACK ;Loop back 3390 INX 3400 BNE LOOKSTACK 3410 ; 3420 PUTINSTACK 3430 STA $D4 ;Save addr of 3440 STX $D5 ;open spot 3450 LDX CIX ;Index 1st char 3460 LDY #255 3470 MOVCHR1 3480 INY 3490 CPY #5 ;Limit of 5 chrs 3500 BEQ INCSTCK ;Br when done 3510 LDA TEXTBUFF,X 3520 STA ($D4),Y 3530 INX 3540 CMP #SPACE ;Move 'til blank 3550 BNE MOVCHR1 3560 INCSTCK 3570 INC LNNOCNT ;Inc stack size 3580 ; 3590 RETCIO2 3600 JMP RETCIO ;Exit to CIO 3610 ; 3620 ; 3630 LOAD? 3640 LDA # LOAD ;chrs to "LOAD " 3660 JSR CMPTEXT 3670 CPY #4 ;Match if "LOAD" 3680 BCC SAVE? ;Br if not match 3690 ; 3700 FINDCOLON 3710 INX ;Find filename 3720 LDA TEXTBUFF,X 3730 BMI RETCIO ;Exit if 3740 CMP #': ;Colon precedes 3750 BNE FINDCOLON 3760 ; 3770 LDA #0 ;Reset save cntr 3780 STA SAVECNT 3790 STA SAVEDFLG ;File not saved 3800 STA LNNOCNT ;and stack cntr 3810 LDY #0 3820 CLRFIRST 3830 STA FILEBOX,Y ;Clear filebox 3840 INY 3850 CPY #12 ;12 chars in box 3860 BNE CLRFIRST 3870 ; 3880 MOVFN 3890 LDY #0 ;Transfer fname 3900 MOVCHR2 ; to filebox 3910 INX 3920 LDA TEXTBUFF,X 3930 BMI RETCIO ;Exit if 3940 CMP #'" ;or quotes 3950 BEQ RETCIO 3960 JSR CONVCHAR ;Make internal 3970 STA FILEBOX,Y ;And poke it 3980 INY 3990 CPY #12 ;Max 12 chars 4000 BNE MOVCHR2 4010 BEQ RETCIO 4020 ; 4030 ; 4040 SAVE? 4050 LDA # SAVE ;in text line 4070 JSR CMPTEXT 4080 CPY #4 ;Blnk not needed 4090 BCC RETCIO ;Br if nope 4100 ; 4110 LDA #255 ;Program saved 4120 STA SAVEDFLG 4130 ; 4140 INC SAVECNT ;Inc # of saves 4150 LDA SAVECNT ;Make sure<9 4160 CMP #10 4170 BCC RETCIO 4180 LDA #0 ;Else reset to 0 4190 STA SAVECNT 4200 ; 4210 ; 4220 RETCIO 4230 LDA #SPACE-32 ;Remove ">" 4240 STA LISTBOX ; prompt 4250 LDX #0 4260 STX CIX ;Reset char indx 4270 LDA #RETURN ;Last char= 4280 LDY ICSTAZ ;Set status 4290 RTS ;Return to CIO 4300 ; 4310 ; 4320 ; 4330 ;Get key from editor: 4340 ;-------------------- 4350 ; Before editor handles 4360 ;keypress or , check for 4370 ;Edit Magic keys, macro keys and 4380 ;console buttons. 4390 ; 4400 EGETKEY 4410 LDA #0 ;Clear pauser 4420 STA ROWCNTR ;for scr output 4430 STA HELPFG ;& press 4440 ; 4450 WAITFORKEY 4460 LDA #0 ;So ctrl-1 does 4470 STA SSFLAG ;nothing 4480 ; 4490 LDA CH ;Key pressed? 4500 CMP #NOKEY 4510 BNE CMPKEY1 ;Br if yep 4520 ; 4530 LDX BRKKEY ; pressed? 4540 BEQ RETEGET ;Exit if yep 4550 ; 4560 LDA HELPFG ;[HELP] pressed? 4570 CMP #17 4580 BEQ HELPUSER ;Br if yep 4590 ; 4600 LDA CONSOL ;Button pressed? 4610 AND #7 4620 CMP #7 4630 BNE CMPBUTTN ;Br if yep 4640 LDA #0 ;Need to know if 4650 STA CONSOLREL ;console has 4660 ; been released 4670 JMP WAITFORKEY ;Loop if nope 4680 ; 4690 ; 4700 RETEGET 4710 JMP (EGETKV) ;Return to o.s. 4720 ; 4730 EXITEGET 4740 PLA ;Abort editor 4750 PLA ;routine in o.s. 4760 LDA #RETURN ;Print to 4770 JSR EPUTCHAR ;move cursor 4780 LDY #BREAK ;And tell CIO 4790 STY BRKKEY ; pressed 4800 RTS 4810 ; 4820 ; 4830 CMPBUTTN 4840 LDY #0-3 ;Look thru E.M. 4850 CMPCONSOL ; consol buttons 4860 INY ;3-byte entries 4870 INY 4880 INY 4890 LDX EMCONSOL,Y ;Exit if end 4900 CPX #7 ; of entries 4910 BEQ WAITFORKEY 4920 CMP EMCONSOL,Y ;Match? 4930 BNE CMPCONSOL ;Loop if nope 4940 ; 4950 LDA CONSOLREL ;Console been 4960 BNE WAITFORKEY ;released? 4970 INC CONSOLREL ;Set flag 4980 ; 4990 GOCONSOL 5000 LDA EMCONSOL+1,Y 5010 STA $D4 ;If found, 5020 LDA EMCONSOL+2,Y 5030 STA $D5 ;jump to addr 5040 JMP ($D4) 5050 ; 5060 ; 5070 HELPUSER 5080 LDA EMFLG ;Ignore 5090 BEQ EGETKEY ;if E.M. off 5100 LDA # HELPMSG ;info 5120 JSR PRINTMSG 5130 JMP EXITEGET ;Abort input 5140 ; 5150 ; 5160 CMPKEY1 5170 LDY EMFLG ;If E.M. off 5180 BEQ CMPKEY2 ;br over macros 5190 LDY #0-3 ;Look for match 5200 CMPMAC ; in macro keys 5210 INY ;3-byte entries 5220 INY 5230 INY 5240 BMI CMPKEY2 ;Emergency exit 5250 LDX MACKEYS,Y 5260 CPX #255 ;End of keys? 5270 BEQ CMPKEY2 ;Br if yup 5280 CMP MACKEYS,Y ;Match? 5290 BNE CMPMAC ;Loop if nope 5300 ; 5310 LDX #NOKEY ;Clear keypress 5320 STX CH 5330 LDA MACKEYS+1,Y ;Get addr of 5340 LDX MACKEYS+2,Y ;macro msg 5350 JSR PRINTMSG ;Print it 5360 JMP WAITFORKEY ;And go back 5370 ; 5380 CMPKEY2 5390 LDY #0-3 ;Look thru E.M. 5400 CMPEM ; special keys 5410 INY ;3-byte entries 5420 INY 5430 INY 5440 LDX EMKEYS,Y ;Last entry? 5450 CPX #255 5460 BEQ RETEGET ;Exit if yep 5470 CMP EMKEYS,Y ;Match? 5480 BNE CMPEM ;Loop if nope 5490 ; 5500 LDX #NOKEY ;Clear keypress 5510 STX CH 5520 LDA EMKEYS+1,Y ;Jump to addr 5530 STA $D4 ; in entry 5540 LDA EMKEYS+2,Y 5550 STA $D5 5560 JMP ($D4) 5570 ; 5580 ; 5590 ;If [START] or SHIFT-ESC 5600 ;pressed, enter LIST BOX. 5610 ; 5620 *** ENTER LIST BOX *** 5630 ENTERLBOX 5640 LDA EMFLG ;Exit if Edit 5650 BNE CLRLBOX ;Magic off 5660 JBACK JMP WAITFORKEY ;Loop back 5670 ; 5680 CLRLBOX 5690 LDX #11 ;Blank out box 5700 LDA #0 ;ie. clr scr mem 5710 CLRBYTE 5720 STA LISTBOX+1,X 5730 DEX ;Box = 12 chars 5740 BPL CLRBYTE ;plus ">" prompt 5750 ; 5760 MAKECURSOR 5770 LDX #0 ;Turn curs off 5780 LDA OLDCHR ;by restoring 5790 STA (OLDADR,X) ;non-inv char 5800 LDA #128 ;And put in box 5810 STA LISTBOX+1 ;pseudo-cursor 5820 ; 5830 STARTINPUT 5840 LDA #0 ;Initialize 5850 STA CHARINDX ;index of char 5860 ; 5870 ;Receive input from keyboard 5880 ;and display in LIST BOX. 5890 ; 5900 GETINPUT 5910 JSR KGETCHAR ;Get a keypress 5920 CPY #0 ;Check for error 5930 BMI EXITLBOX ;Exit if 5940 STA SAVCHAR ;Save keypress 5950 ; 5960 NUMBER? 5970 CMP #', ;Allow comma 5980 BEQ CHCKINDX 5990 CMP #'0 ;and 0-9 only 6000 BCC DELETE? 6010 CMP #'9+1 ;in listbox 6020 BCS DELETE? 6030 ; 6040 CHCKINDX 6050 LDX CHARINDX ;Ignore key if 6060 CPX #11 ; box is full 6070 BCC PUTINBOX ;Br if not full 6080 JMP GETINPUT ;Loop if it is 6090 ; 6100 PUTINBOX 6110 JSR CONVCHAR ;Put num/comma 6120 STA LISTBOX+1,X ;in box 6130 INC CHARINDX ;Point nxt char 6140 BNE PUTCURSOR ;and branch 6150 ; 6160 DELETE? 6170 CMP #DELETE ;Allow 6180 BNE PUTCURSOR ;Br if it isnt 6190 ; 6200 CLRCURSOR 6210 LDX CHARINDX ;Backspace if 6220 BEQ PUTCURSOR ;chars in box 6230 LDA #0 ;Erase last char 6240 STA LISTBOX+1,X 6250 DEC CHARINDX ;One less char 6260 ; 6270 PUTCURSOR 6280 LDX CHARINDX ;Put curs block 6290 LDA #128 ;in listbox 6300 STA LISTBOX+1,X 6310 ; 6320 RETURN? 6330 LDA SAVCHAR ;Done if 6340 CMP #RETURN 6350 BNE ESC? ;Br if not 6360 LDA #0 ;Clr p-cursor 6370 STA LISTBOX+1,X 6380 JMP LISTLINES ;List contents 6390 ; 6400 ESC? 6410 CMP #ESC ;Abort if 6420 BEQ EXITLBOX ;Br if yep 6430 JMP GETINPUT ;Else loop back 6440 ; 6450 ;Leave input from LIST BOX and 6460 ;move back to normal screen. 6470 ; 6480 EXITLBOX 6490 LDX CHARINDX ;Remove 6500 LDA #0 ;pseudo-cursor 6510 STA LISTBOX+1,X 6520 JMP EXITEGET ;Abort input 6530 ; 6540 ; 6550 ;If [SELECT] or CTRL-ESC 6560 ;pressed, list contents of LIST 6570 ;BOX by returning LIST+lnnos 6580 ;to CIO as inputted line. 6590 ; 6600 *** LIST LINES *** 6610 ; 6620 LISTLINES 6630 LDA EMFLG ;Exit if EM off 6640 BNE MOVLIST 6650 JMP WAITFORKEY ;Loop back 6660 ; 6670 MOVLIST 6680 LDX #5 ;Move "LIST " 6690 MOVCHR3 ; into text buffer 6700 LDA LIST-1,X 6710 STA TEXTBUFF-1,X 6720 DEX 6730 BNE MOVCHR3 6740 ; 6750 MOVCHR4 6760 CPX CHARINDX ;Put chars in 6770 BEQ MOVHILNNO? ; listbox 6780 LDA LISTBOX+1,X ;after 6790 CLC ; "LIST " 6800 ADC #32 ;Conv to ascii 6810 STA TEXTBUFF+5,X 6820 INX 6830 BNE MOVCHR4 6840 ; 6850 MOVHILNNO? 6860 CMP #', ;If last chr="," 6870 BNE SETICB ;put "32767" 6880 ; (sorry MAC/65 users) 6890 LDY #0 6900 MOV32767 6910 LDA HILNNO,Y ;"32767" in 6920 STA TEXTBUFF+5,X ;ascii code 6930 INX 6940 INY 6950 CPY #5 6960 BNE MOV32767 6970 ; 6980 SETICB 6990 TXA ;Tell editor 7000 CLC ;where input is 7010 ADC #128+5 7020 STA ICBALZ ;Zero-page IOCB 7030 LDA # >TEXTBUFF 7040 STA ICBALZ+1 7050 ; 7060 SETUPSCR 7070 LDA #0 ;Clear esc flag 7080 STA ESCFLG ;in case pressed 7090 STA SSFLAG ;and ctrl-1 flg 7100 LDA #CLEAR ;so screen will 7110 JSR EPUTCHAR ;clear and list 7120 ; 7130 LDA LNNOCNT ;Save size of 7140 STA STCKCNT ;stack and 7150 ; 7160 LDA #0 ;Reset stack of 7170 STA LNNOCNT ;lnnos edited 7180 PLA ;Throw out 7190 PLA ;return addrs 7200 PLA 7210 PLA 7220 LDY #1 ;Set status to 7230 STY ICSTAZ ;no error 7240 JMP RETCIO ;Go right to CIO 7250 ; 7260 ; 7270 ;If [OPTION] or SHIFT-CTRL-ESC 7280 ;pressed, toggle Edit Magic 7290 ;on/off. When turned on, VBI 7300 ;routine will re-display top 7310 ;status line. 7320 ; 7330 *** TOGGLE EDIT MAGIC *** 7340 TOGEDTMAG 7350 LDA #1 ;Toggle Edit 7360 EOR EMFLG ;Magic flag 7370 STA EMFLG ;on/off 7380 BEQ EMOFF ;Br if now off 7390 ; 7400 EMON 7410 JMP WAITFORKEY ;Get s'more 7420 ; 7430 EMOFF 7440 LDA SAVSDLSTL ;Restore old 7450 STA SDLSTL ; display list 7460 LDA SAVSDLSTL+1 7470 STA SDLSTL+1 7480 ; 7490 LDA SAVCOLR1 ;Restore char 7500 STA COLOR1 ;brightness 7510 LDA #0 ;and black 7520 STA COLOR4 ;border color 7530 ; 7540 JMP WAITFORKEY ;Go back 7550 ; 7560 ; 7570 ;If key (SHIFT-<) 7580 ;pressed and cursor not on left 7590 ;margin, ignore it. 7600 ; 7610 *** HANDLE SHIFT-CLEAR *** 7620 SHIFTCLR 7630 LDA EMFLG ;Exit if EM off 7640 BEQ CLRIT 7650 ; 7660 LDA LOGCOL ;Start of 7670 CMP LMARGIN ;logical line? 7680 BNE IGNOREIT ;Br if nope 7690 CLRIT 7700 LDA #54+64 ;Replace 7710 STA CH ;keypress 7720 JMP RETEGET ;and exit 7730 IGNOREIT 7740 JMP WAITFORKEY ;Ignore 7750 ; 7760 ; 7770 ; 7780 ;Put character to editor: 7790 ;------------------------ 7800 ; Use faster print routine to 7810 ;speed up screen output. Also 7820 ;allow pause, and check for 7830 ;line number preceding text. 7840 ;If lnno in stack, mark it. 7850 ; 7860 PUTENTRY 7870 STA SAVCHAR ;Save char 7880 ; 7890 LDY EMFLG ;Exit if Edit 7900 BEQ GO.OS ;Magic off 7910 ; 7920 LDY DINDEX ;If not txt mode 7930 BEQ BREAK? 7940 GO.OS 7950 JMP EPUTCHAR ;let o.s. print 7960 ; 7970 BREAK? 7980 LDY BRKKEY ;Abort if 7990 BNE CTRL1? 8000 JMP ABORTOUTPUT 8010 ; 8020 CTRL1? 8030 LDY SSFLAG ;Loop if CTRL-1 8040 BNE BREAK? ;pressed 8050 ; 8060 ;If start of text line, check 8070 ;for linenumber. If line has one 8080 ;and matches one in stack, mark 8090 ;the line. 8100 ; 8110 LDX LMARGIN ;Room to mark? 8120 BEQ PAUSEON? ;Br if nope 8130 CPX LOGCOL ;Start of line? 8140 BCC PAUSEON? ;Br if nope 8150 ; 8160 LDX STCKCNT ;Have any lnnos 8170 BEQ PAUSEON? ;been edited? 8180 ; 8190 CMP #'0 ;Is char part 8200 BCC PAUSEON? ;of a lnno? 8210 CMP #'9+1 8220 BCS PAUSEON? ;Br if nope 8230 ; 8240 LDY #255 ;Skip over 8250 SKIP0 ; leading zeroes 8260 INY 8270 LDA (INBUFF),Y ;Points to # 8280 CMP #'0 ;Zero char? 8290 BEQ SKIP0 ;Loop if yup 8300 ; 8310 LDA # LNNOSTACK ;to see if 8340 STA $E1 ; same lnno 8350 ; has been edited 8360 TYA ;Indxes 1st char 8370 CLC 8380 ADC INBUFF 8390 STA $E2 ;Point to lnno 8400 LDA INBUFF+1 8410 ADC #0 8420 STA $E3 8430 ; 8440 LDA STCKCNT ;Save counter 8450 STA $E4 8460 ; 8470 LOOKLNNO 8480 LDY #0 8490 DEC $E4 ;Done when all 8500 BMI PAUSEON? ;lnnos checked 8510 LOOKCHR 8520 LDA ($E2),Y ;Char from line 8530 TAX ;Save it 8540 AND #127 ;In case inverse 8550 CMP ($E0),Y ;Char in stack 8560 BNE NEXTLNNO 8570 CMP #SPACE ;Done if blank 8580 BEQ MATCHLNNO 8590 INY ;Next char 8600 CPY #5 ;Max 5 chars 8610 BEQ MATCHLNNO ;Assume match 8620 TXA ;Last # char? 8630 BPL LOOKCHR ;Loop if not yet 8640 ; 8650 LDA ($E0),Y ;Is next char 8660 CMP #SPACE ;a blank? 8670 BNE NEXTLNNO ;Br if no 8680 ; 8690 MATCHLNNO ; Match found! 8700 DEC OLDADR+1 ;Mark line by 8710 LDY #255 ;putting arrow 8720 LDA #'.+64 ;left of cursor 8730 STA (OLDADR),Y 8740 INC OLDADR+1 8750 JMP PAUSEON? 8760 ; 8770 NEXTLNNO 8780 CLC 8790 LDA #5 ;Look at next 8800 ADC $E0 ;lnno in stack 8810 STA $E0 8820 LDA $E1 8830 ADC #0 8840 STA $E1 8850 JMP LOOKLNNO 8860 ; 8870 ; 8880 PAUSEON? 8890 LDA SAVCHAR 8900 LDY PAUSEFLG 8910 BEQ FASTPRNT 8920 ; 8930 LDY KBCODE ;If last key='C' 8940 CPY #18 8950 BNE COUNTLN 8960 LDY #NOKEY ;clear keypress 8970 STY CH 8980 JMP FASTPRNT ;Don't pause 8990 ; 9000 CLEAR? 9010 CMP #CLEAR ;If char 9020 BNE COUNTLN ;reset row cntr 9030 LDY #0 ;only if screen 9040 CPY DSPFLG ;will clear 9050 BNE COUNTLN ;Br if not 9060 CPY ESCFLG 9070 BNE COUNTLN ;Br if not again 9080 STY ROWCNTR ;Clear # lines 9090 JMP GO.OS ;and print 9100 ; 9110 COUNTLN 9120 CMP #RETURN ;Keep count of 9130 BEQ INCLN ;lines printed 9140 LDX COLCRS 9150 CPX RMARGIN 9160 BCC FASTPRNT 9170 INCLN INC ROWCNTR 9180 ; 9190 ;Every 22nd line printed, pause 9200 ;output and wait for keypress. 9210 ; 9220 PAUSESCR? 9230 JSR EPUTCHAR ;Print char 9240 LDX ROWCNTR ;Time to pause? 9250 CPX #21 9260 BCC LEAVE ;Br if no 9270 ; 9280 LDY #0 ;Reset # rows 9290 STY ROWCNTR ;printed 9300 STY CONSOL ;Click speaker 9310 ; 9320 PUTPROMPT 9330 LDX # <[MSG2-MSGS] 9340 JSR PUTMSG ;Put "press key" 9350 ; msg on top line 9360 LDA #NOKEY ;Clear keypress 9370 STA CH 9380 WAITFORKEY2 9390 CMP CH ;Wait for user 9400 BNE CONTOUTPUT ;to hit a key 9410 LDX BRKKEY ; or 9420 BNE WAITFORKEY2 9430 ; 9440 LDX # <[MSG1-MSGS] 9450 JSR PUTMSG ;Clr prompt 9460 ; 9470 ABORTOUTPUT 9480 LDY #BREAK ; pressed 9490 STY BRKKEY 9500 RTS 9510 ; 9520 CONTOUTPUT 9530 STA CH ;Clear keypress 9540 LDY #0 ;Clear ctrl-1 9550 STY SSFLAG ;pause 9560 CLRPROMPT 9570 LDX # <[MSG1-MSGS] 9580 JSR PUTMSG ;Restore title 9590 ; 9600 LEAVE RTS ;Go back to CIO 9610 ; 9620 ;Put character directly in 9630 ;screen memory unless scrolling 9640 ;or control character. 9650 ; 9660 FASTPRNT 9670 LDX COLCRS ;Will it scroll? 9680 CPX RMARGIN 9690 BCS PRINTCHR ;Br if maybe 9700 TAX ;Save char 9710 AND #127 9720 CMP #125 ;Is char a 9730 BCS PRINTIT ;non-control 9740 CMP #32 ;char? 9750 BCS PUTIT 9760 CMP #27 9770 BCC PUTIT 9780 ; 9790 PRINTIT 9800 TXA ;Regain char 9810 PRINTCHR 9820 JMP EPUTCHAR ;Let o.s. print 9830 ; 9840 PUTIT 9850 TXA ;Regain char 9860 JSR CONVCHAR ;Make internal 9870 LDY #0 ;Put char in 9880 STA (OLDADR),Y ;curs pos in 9890 ; screen mem 9900 MOVCURS 9910 INC COLCRS ;Move cursor 9920 INC LOGCOL ;pointers to 9930 INC OLDADR ;next column 9940 BNE PUTCURS 9950 INC OLDADR+1 9960 ; 9970 PUTCURS 9980 LDA (OLDADR),Y ;Save char 9990 STA OLDCHR ;under curs and 010000 EOR #128 ;inverse it 010010 STA (OLDADR),Y 010020 ; 010030 EXITPUTCHR RTS ;Return to CIO 010040 ; 010050 ; 010060 ; 010070 ;Handle VBI: 010080 ;----------- 010090 ;Before exiting vert. blank 010100 ;int, make sure Edit Magic's 010110 ;settings are still intact. 010120 ; 010130 XITVBI 010140 LDA EMFLG :Edit Magic on? 010150 BEQ EXITVBI ;Br if nope 010160 ; 010170 LDA SDLSTL+1 ;If not using 010180 CMP # >DLIST ;our disp list, 010190 BEQ SETCOLR 010200 STA SAVSDLSTL+1 ;save addr 010210 LDA SDLSTL ; of theirs 010220 STA SAVSDLSTL 010230 LDA SAVMSC ;Let dl know 010240 STA SCRMEM ;where scr is 010250 LDA SAVMSC+1 010260 STA SCRMEM+1 010270 LDA # DLIST 010300 STA SDLSTL+1 010310 ; 010320 LDA #1 ;Reset pause for 010330 STA PAUSEFLG ;listing 010340 ; 010350 LDA COLOR1 ;If new char 010360 CMP #12 ;brightness 010370 BEQ SETCOLR 010380 STA SAVCOLR1 ;save it 010390 ; 010400 SETCOLR 010410 LDA #12 ;Brighten chars 010420 STA COLOR1 010430 STA COLPF1 010440 LDA #2 ;Lighten border 010450 STA COLOR4 010460 ; 010470 LDA EPUT ;Make sure our 010480 STA ICPTL ;put char vect 010490 LDA EPUT+1 ;is used 010500 STA ICPTL+1 010510 ; 010520 EXITVBI ; Restore regs 010530 PLA ;(Tracy DuMont 010540 TAY ;said she'd pay 010550 PLA ;me a dollar if 010560 TAX ;I put her name 010570 PLA ;here.) 010580 RTI ;Leave vbi 010590 ; 010600 ; 010610 ; 010620 *** SUBROUTINES *** 010630 ; ----------- 010640 ; 010650 ;Jump to o.s. GET from editor 010660 ; 010670 EGETCHAR 010680 LDA SAVEGETV+1 010690 PHA 010700 LDA SAVEGETV 010710 PHA 010720 RTS 010730 ; 010740 ; 010750 ;Compare start of entered text 010760 ;with up to 5 characters. 010770 ; 010780 CMPTEXT 010790 STA $D4 ;Passed addr of 010800 STX $D5 ;text to compare 010810 LDX CIX ;Indx of 1st chr 010820 LDY #255 010830 CMPCHR 010840 INY ;Check up to 5 010850 CPY #5 ;characters 010860 BEQ MATCH ;Br if done 010870 LDA TEXTBUFF,X ;Char from ln 010880 AND #127 ;In case inverse 010890 CMP #96 ;Lowercase? 010900 BCC SAMECHR? ;Br if no 010910 SEC ;Make uppercase 010920 SBC #32 010930 SAMECHR? 010940 CMP ($D4),Y ;Char from E.M. 010950 BNE NOMATCH 010960 INX 010970 CMP #SPACE ;Blank ends 010980 BNE CMPCHR 010990 ; 011000 MATCH 011010 LDY #128 ;Set N-flg 011020 RTS 011030 ; 011040 NOMATCH 011050 LDA $D4 ;Restore arg adr 011060 LDX $D5 011070 CPY #0 ;Clear N-flg 011080 RTS 011090 ; 011100 ; 011110 ;Convert char from ASCII to 011120 ;internal (screen). 011130 ; 011140 CONVCHAR 011150 STX SAVREG ;Save xreg 011160 PHA ;Acc=ascii char 011170 AND #127 ;Make non-inv 011180 TAX ;Save in xreg 011190 PLA ;Restore char 011200 CPX #96 ;Lowercase? 011210 BCS NOTRNS ;Br if yep 011220 CPX #32 ;Graphics char? 011230 BCS TRNS2 ;Br if nope 011240 TRNS1 011250 CLC ;Conv grphic chr 011260 ADC #64 011270 BCC NOTRNS 011280 TRNS2 011290 SEC ;Conv uppercs 011300 SBC #32 011310 NOTRNS 011320 LDX SAVREG ;Restore xreg 011330 RTS 011340 ; 011350 ; 011360 ;Print a message. 011370 ;Passed: Acc&xreg contain addr 011380 ;of message. Print char by 011390 ;char until zero value found. 011400 ; 011410 PRINTMSG 011420 STA $D4 ;Save lo addr 011430 STX $D5 ;Save hi addr 011440 LDY #0 011450 PRINTCHAR 011460 STY SAVREG ;Save index 011470 LDA ($D4),Y ;Get msg char 011480 BEQ EXITPRNT ;Exit if 0 011490 JSR EPUTCHAR 011500 CPY #0 ; pressed? 011510 BMI EXITPRNT ;Exit if 011520 LDY SAVREG ;Restore index 011530 INY 011540 BNE PRINTCHAR ;Loop back 011550 INC $D5 011560 BNE PRINTCHAR 011570 ; 011580 EXITPRNT 011590 RTS 011600 ; 011610 ; 011620 ;Print a single character. 011630 ; 011640 EPUTCHAR 011650 TAY ;Acc=char 011660 LDA SAVEPUTV+1 ;Push vector 011670 PHA ; to stack 011680 LDA SAVEPUTV 011690 PHA 011700 TYA ;Restore char 011710 RTS ;Jump to o.s. 011720 ; 011730 ; 011740 ;Put a message in MSG BOX in 011750 ;Edit Magic screen line. 011760 ; 011770 PUTMSG 011780 LDY #0 011790 PUTBYTE 011800 LDA MSGS,X ;Xreg indxs msg 011810 STA MSGBOX,Y 011820 INX 011830 INY 011840 CPY #11 ;Msgbox=11 chars 011850 BNE PUTBYTE 011860 RTS 011870 ; 011880 ; 011890 ;Get a keypress. 011900 ; 011910 KGETCHAR 011920 LDA KHANDTAB+5 ;Jump to o.s. 011930 PHA 011940 LDA KHANDTAB+4 011950 PHA 011960 RTS 011970 ; 011980 ; 011990 .IF *>$CFFF 012000 .ERROR "EDIT MAGIC CODE TOO LARGE!" 012010 .ENDIF 012020 ; 012030 ; 012040 *** SCREEN DATA *** 012050 ; 012060 *= DISPLIST 012070 ; 012080 DLIST 012090 .BYTE $70,$50,66 012100 .WORD EMLINE 012110 .BYTE $10,66 012120 SCRMEM *= *+2 012130 .BYTE 2,2,2,2,2,2,2 012140 .BYTE 2,2,2,2,2,2,2,2,2,2,2 012150 .BYTE 2,2,2,2,2,65 012160 .WORD DLIST 012170 ; 012180 EMLINE 012190 LISTBOX .SBYTE " |" 012200 MSGBOX .SBYTE "Edit Magic|" 012210 FILEBOX .SBYTE " |" 012220 BAKUPCNT .SBYTE "0" 012230 ; 012240 ; 012250 MSGS 012260 MSG1 .SBYTE "Edit Magic" 012270 MSG2 .SBYTE "press a key" 012280 ; 012290 ; 012300 *** MACROS *** 012310 ; 012320 *= MACLIST 012330 ; 012340 ;Table for macro keys. 012350 ;Entries consist of 3 bytes: 012360 ;1st is internal value of 012370 ;keypress, 2nd & 3rd are 012380 ;address of text to print. 012390 ;Text is printed until zero 012400 ;found. 012410 ; 012420 MACKEYS 012430 .BYTE 52+64+128 ;s-c-BS 012440 .WORD SHFTCTRLDEL 012450 .BYTE 55+64+128 ;s-c-INSERT 012460 .WORD SHFTCTRLINS 012470 .BYTE 40+64+128 ;s-c-R 012480 .WORD SAVTBUFF 012490 .BYTE 255 012500 ; 012510 ; 012520 *** MISC STORAGE *** 012530 ; 012540 *= MISC 012550 ; 012560 EMFLG .BYTE 1 012570 SAVSDLSTL *= *+2 012580 SAVEGETV *= *+2 012590 SAVEPUTV *= *+2 012600 SAVCOLR1 .BYTE 10 012610 SAVECNT .BYTE 0 012620 SAVEDFLG .BYTE 0 012630 STCKCNT .BYTE 0 012640 LNNOCNT .BYTE 0 012650 ROWCNTR .BYTE 0 012660 SAVCHAR .BYTE 0 012670 SAVREG .BYTE 0 012680 CHARINDX .BYTE 0 012690 CONSOLREL .BYTE 0 012700 ; 012710 LOAD .BYTE "LOAD " 012720 SAVE .BYTE "SAVE " 012730 LIST .BYTE "LIST " 012740 HILNNO .BYTE "32767" 012750 ; 012760 EGETKV .WORD $F2FD 012770 ; 012780 SAVTBUFF .BYTE 0 012790 *= *+127 012800 ; 012810 LNNOSTACK 012820 *= *+[24*5] 012830 ; 012840 ; 012850 ;Table for function keys. 012860 ;EMCONSOL/EMKEYS has 3-byte 012870 ;entries: console button/key 012880 ;plus address to jump to if 012890 ;pressed. 012900 ; 012910 EMCONSOL 012920 .BYTE 6 ; [start] 012930 .WORD ENTERLBOX 012940 .BYTE 5 ; [select] 012950 .WORD LISTLINES 012960 .BYTE 3 ; [option] 012970 .WORD TOGEDTMAG 012980 .BYTE 7 012990 ; 013000 ; 013010 EMKEYS 013020 .BYTE 28+64 ; shift-ESC 013030 .WORD ENTERLBOX 013040 .BYTE 28+128 ; ctrl-ESC 013050 .WORD LISTLINES 013060 .BYTE 28+64+128 ;s-c-ESC 013070 .WORD TOGEDTMAG 013080 .BYTE 54+64 ; shift-< 013090 .WORD SHIFTCLR 013100 .BYTE 255 013110 ; 013120 ; 013130 HELPMSG 013140 .BYTE "$) Edit Magic KEYS:",155 013150 .BYTE " (s=shift,c=control)",155,155 013160 .BYTE "[START] or s-ESC = Edit LIST BOX",155 013170 .BYTE "[SELECT] or c-ESC = List #'s in BOX",155 013180 .BYTE "[OPTION] or s-c-ESC = Toggle EM on/off",155 013190 .BYTE "s-c-R = Recalls last line entered",155 013200 .BYTE "s-c-BS = Deletes succeeding 40 chars",155 013210 .BYTE "s-c-INSERT = Inserts 10 lines",155 013220 .BYTE "s-CLEAR = Cursor must be on lft margin",155 013230 .BYTE "C = Continuous output (when listing)",155,155 013240 .BYTE " [HELP] = Prints this",155,155 013250 .BYTE 0 013260 ; 013270 ; 013280 SHFTCTRLDEL .BYTE "$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-$-",0 013290 ; 013300 SHFTCTRLINS .BYTE "..........",0 013310 ; 013320 ; 013330 .IF *>DISPLIST 013340 .ERROR "MISC. STORAGE AREA TOO LARGE!" 013350 .ENDIF 013360 ; 013370 *= $F25D 013380 .WORD EGETKEY 013390 ; 013400 *= EHANDTAB 013410 ; 013420 EOPEN *= *+2 013430 ECLOSE *= *+2 013440 EGET .WORD GETENTRY-1 013450 EPUT .WORD PUTENTRY-1 013460 ESTAT *= *+2 013470 ESPEC *= *+2 013480 EINIT *= *+3 013490 ; 013500 ; 013510 ;The code has now been stored 013520 ;in o.s. RAM. If loaded as an 013530 ;AUTORUN.SYS file,control will 013540 ;eventually revert back to the 013550 ;coldstart routine--which has 013560 ;been overwritten! So, check 013570 ;for this situation, and do 013580 ;coldstart work so we needn't 013590 ;return there. 013600 ; 013610 *= INITCODE ;Here again 013620 ; 013630 RUN 013640 LDA COLDST ;Powerup? 013650 BNE FINISH.COLD ;Br if yes 013660 RTS ;Return to DOS 013670 ; 013680 FINISH.COLD 013690 LDX #255 ;Reset stack 013700 TXS ;pointer 013710 LDA #1 ;Successful 013720 STA $09 ;disk boot 013730 JSR $E739 013740 LDA #0 ;So no reboot 013750 STA COLDST 013760 LDA TRAMSZ ;Lft cart? 013770 BEQ GO.DOS ;Br if no 013780 LDA $BFFD ;Go to cart? 013790 AND #$04 013800 BEQ GO.DOS ;Br if no 013810 JMP ($BFFA) ;Jump to cart 013820 GO.DOS 013830 JMP (DOSVEC) ;Jump to DOS 013840 ; 013850 ; 013860 *= RUNADR 013870 .WORD RUN